This is an R Markdown Notebook. When you execute code within the notebook, the results appear beneath the code.

This version of beta calculation is used for the theoretical method/results of the paper. For reference: the last update was Dec 2018 for an R notebook. This R notebook is an updated and more sophisticated version.

Constants used are listed at the start of this script.

setwd("D:/R program")
The working directory was changed to D:/R program inside a notebook chunk. The working directory will be reset when the chunk is finished running. Use the knitr root.dir option in the setup chunk to change the working directory for notebook chunks.
source("inspack.R")
Loading required package: tidyverse
-- Attaching packages --------------------------------------- tidyverse 1.2.1 --
v ggplot2 3.2.1     v purrr   0.3.3
v tibble  2.1.3     v dplyr   0.8.3
v tidyr   1.0.0     v stringr 1.4.0
v readr   1.3.1     v forcats 0.4.0
-- Conflicts ------------------------------------------ tidyverse_conflicts() --
x dplyr::filter() masks stats::filter()
x dplyr::lag()    masks stats::lag()
Loading required package: plyr
-----------------------------------------------------------------------------------------------------
You have loaded plyr after dplyr - this is likely to cause problems.
If you need functions from both plyr and dplyr, please load plyr first, then dplyr:
library(plyr); library(dplyr)
-----------------------------------------------------------------------------------------------------

Attaching package: 㤼㸱plyr㤼㸲

The following objects are masked from 㤼㸱package:dplyr㤼㸲:

    arrange, count, desc, failwith, id, mutate, rename, summarise, summarize

The following object is masked from 㤼㸱package:purrr㤼㸲:

    compact

Loading required package: grid
Loading required package: gridExtra

Attaching package: 㤼㸱gridExtra㤼㸲

The following object is masked from 㤼㸱package:dplyr㤼㸲:

    combine

Loading required package: plotly
Registered S3 method overwritten by 'data.table':
  method           from
  print.data.table     
Registered S3 methods overwritten by 'htmltools':
  method               from         
  print.html           tools:rstudio
  print.shiny.tag      tools:rstudio
  print.shiny.tag.list tools:rstudio
Registered S3 method overwritten by 'htmlwidgets':
  method           from         
  print.htmlwidget tools:rstudio

Attaching package: 㤼㸱plotly㤼㸲

The following objects are masked from 㤼㸱package:plyr㤼㸲:

    arrange, mutate, rename, summarise

The following object is masked from 㤼㸱package:ggplot2㤼㸲:

    last_plot

The following object is masked from 㤼㸱package:stats㤼㸲:

    filter

The following object is masked from 㤼㸱package:graphics㤼㸲:

    layout

Loading required package: ggthemes
Loading required package: viridis
Loading required package: viridisLite
Loading required package: data.table
data.table 1.12.6 using 6 threads (see ?getDTthreads).  Latest news: r-datatable.com

Attaching package: 㤼㸱data.table㤼㸲

The following objects are masked from 㤼㸱package:dplyr㤼㸲:

    between, first, last

The following object is masked from 㤼㸱package:purrr㤼㸲:

    transpose

Loading required package: Rmisc
Loading required package: lattice

#values needed 
K= 1.38064852*(10)^-23 #m2 kg/ s2 K boltzmann constant
mu= 1.126*(10)^-3 #kg/m s dynamic viscosity in 18C
v= 1.099*(10)^-6 #m2/s kinematic viscosity in 18C
Reh_calc= 2.3E-6 #in m radius Ehux
Reh_naked= 1.8E-6 #in m radius Ehux
Reh_lith = 1.5E-6 #in m radius
Rehv= 90*(10)^-9 #in m radius virus
Temp = 18+273.15 #temp in kelvin, here assuming 18C
Den_OcM = 1.05 #g/cm3 density organic cell matter
Den_CH2O= 1.025 #g/cm3 density seawater at 18C
CcNum <- 0.9*((10)^3)
NcNum <- 0.1*((10)^3)
ViNum <- (CcNum+NcNum)*10
LiNum <- CcNum*50

Calculating for Brownian motion

#Brownian motion (BM)
#1. make a data frame
BM <- data.frame (group=as.factor(c("Nc", "Cc", "Li")), rad= c(1.8E-6, 2.3E-6, 1.5E-6)) 
#2. calculate beta (beta)
BM$beta_BM <- ((2*(K*(10)^4)*Temp*(((BM$rad+Rehv)*100)^2))/((3*mu*10)*(BM$rad*Rehv*1e4)))*86400 #cm3/d
# go back to this later
#3. calculate encounters (E)
BM$E_BM <- BM$beta_BM*ViNum
BM

Differential settling

#Differential settling (DS)
#1. read in PIC data
library(readr) #always use readr not baseR
setwd("D:/R program")
The working directory was changed to D:/R program inside a notebook chunk. The working directory will be reset when the chunk is finished running. Use the knitr root.dir option in the setup chunk to change the working directory for notebook chunks.
PIC <- read_csv("Postdoc-R/CSV Files/PIC.csv")
Parsed with column specification:
cols(
  Strain = col_character(),
  Replicate = col_double(),
  TC = col_double(),
  AC = col_double(),
  Cellcount = col_double()
)
PIC$Strain <- as.factor(PIC$Strain)
PIC$Replicate <- as.factor(PIC$Replicate)
#2. calculate PIC for cell
PIC$PIC <- PIC$TC-PIC$AC
PIC$PICpercell <- (PIC$PIC/PIC$Cellcount)*(10)^-3#in g
PIC$PICpercellpg <- PIC$PICpercell*1e12
ggplotly(ggplot(data=PIC, aes(x=Strain, y=PICpercellpg)) + geom_boxplot()+geom_point(size=2) +theme_Publication())

#3a. calculate density of cells (den_cell)
PIC <- mutate(PIC, group = ifelse(PICpercellpg < 4 , "naked", "calcified"))
ggplotly(ggplot(data=PIC, aes(x=group, y=PICpercellpg)) + geom_boxplot()+geom_point(size=2, aes(color=Strain))+ theme_Publication())
plotly.js does not (yet) support horizontal legend items 
You can track progress here: 
https://github.com/plotly/plotly.js/issues/53 

PIC <- mutate(PIC, rad = ifelse(group == "naked" , 1.8E-6,  2.3E-6)) #in m
PIC$volume <- (4/3)*pi*(PIC$rad*100)^3 #in cm3
PIC$Den_cell <- PIC$PICpercell/PIC$volume #g/cm3
PIC$Den_celltotal <- PIC$Den_cell+Den_OcM
ggplotly(ggplot(data=PIC, aes(x=Strain, y=Den_celltotal, color=group)) + geom_boxplot()+geom_point(size=2) 
         +theme_Publication())
plotly.js does not (yet) support horizontal legend items 
You can track progress here: 
https://github.com/plotly/plotly.js/issues/53 

#some strains that are "naked" have PIC<2. I chose to ignore this since in the lm model I do not use
#strain as a factor, rather data is treated as a whole (e.g., no grouping)
#assume grouping
PIC$group2 <- case_when(
  PIC$PICpercellpg <2  ~ "naked",
  PIC$PICpercellpg >2 & PIC$PICpercellpg < 4 ~ "naked/calcified uncertain",
  PIC$PICpercellpg >4 & PIC$PICpercellpg < 10 ~ "moderately calcified",
  PIC$PICpercellpg >10 ~ "heavily calcified", 
  TRUE ~ as.character(PIC$PICpercellpg)
)
PIC$group2 <- factor (PIC$group2,levels= c("naked", "naked/calcified uncertain",
                                                       "moderately calcified", "heavily calcified"),
                                                       labels = c("naked", "naked/calcified uncertain",
                                                                  "moderately calcified", "heavily calcified"))
#3b. calculate PIC and density for lith
PIC$perlith <- PIC$PICpercell/14 #in g, assuming 20 liths attached
PIC$perlithpg <- PIC$perlith*1e12 #in pg
PIC$Denlith <- case_when(
  PIC$group2 == "naked"  ~ 1.025, 
  PIC$group2 == "naked/calcified uncertain" ~ 1.025,
  PIC$group2 == "moderately calcified" ~ 2,
  PIC$group2 == "heavily calcified" ~ 2.6)
ggplotly(ggplot(data=PIC, aes(x=group, y=Denlith, color=group)) + geom_boxplot()+geom_point(size=2) 
         +theme_Publication())
plotly.js does not (yet) support horizontal legend items 
You can track progress here: 
https://github.com/plotly/plotly.js/issues/53 
#4. calculate sinking velocity of cells,liths, and viruses
PIC$SinkVel <- ((2*((PIC$rad*100)^2)*(981)*(PIC$Den_celltotal-Den_CH2O))/(9*(mu*10)))*864 #meter per day
PIC$SinkVel_lith <- ((2*((Reh_lith*100)^2)*(981)*(PIC$Denlith-Den_CH2O))/(9*(mu*10)))*864 #meter per day
Ehv_SinkVel <- ((2*((Rehv*100)^2)*(981)*(Den_CH2O-Den_CH2O))/(9*(mu*10)))*864  #equals to 0
#g is converted to per day, 864 is the one that converts cm/s to m/day
#plot sinking velocity vs calcification
ggplot(data=PIC, aes(x=PICpercellpg, y=SinkVel, color=Strain, shape=group2)) + geom_point(size=5)+theme_Publication()+
    labs(y = expression("Sinking velocity"~("m"~day^-1)), x = expression("PIC pg"~cell^-1)) +
    theme(legend.direction = "horizontal", legend.box = "vertical", legend.title = element_blank()) 

ggplot(data=PIC %>% filter (group=="calcified"), aes(x=perlithpg, y=SinkVel_lith, color=group2, shape=group2)) + 
  geom_point(size=5)+theme_Publication()+
  labs(y = expression("Sinking velocity"~("m"~day^-1)), x = expression("PIC pg"~lith^-1)) +
    theme(legend.direction = "horizontal", legend.box = "vertical", legend.title = element_blank()) 

#5. calculate betas for DS
PIC$beta_DS <-(pi*(((PIC$rad+Rehv)*100)^2)*(abs((PIC$SinkVel-Ehv_SinkVel)/864)))*86400 #in encounters cm3/day
PIC$beta_DS_lith <- (pi*(((Reh_lith+Rehv)*100)^2)*(abs((PIC$SinkVel_lith-Ehv_SinkVel)/864)))*86400 #in encounters cm3/day
ggplot(data=PIC, aes(x=PICpercellpg, y=beta_DS, color=Strain,  shape=group2)) + geom_point(size=5)+theme_Publication()+
  labs(y = expression(beta~("Encounters"~cm^3~day^-1)), x = expression("PIC pg"~cell^-1))  +
scale_y_log10(
        breaks = scales::trans_breaks("log10", function(x) 10^x, n=2),
        labels = scales::trans_format("log10", scales::math_format(10^.x))) + annotation_logticks(sides="l")+
      theme(legend.direction = "horizontal", legend.box = "vertical", legend.title = element_blank()) 

ggplot(data=PIC %>% filter (group=="calcified"), aes(x=perlithpg, y=beta_DS_lith, color=group2, shape=group2)) + geom_point(size=5)+theme_Publication()+
  labs(y = expression(beta~("Encounters"~cm^3~day^-1)), x = expression("PIC pg"~lith^-1))  +
scale_y_log10(
        breaks = scales::trans_breaks("log10", function(x) 10^x, n=2),
        labels = scales::trans_format("log10", scales::math_format(10^.x))) + annotation_logticks(sides="l")+
      theme(legend.direction = "horizontal", legend.box = "vertical", legend.title = element_blank()) 

#6. calculate encounters
PIC$E_DS <- (PIC$beta_DS*ViNum) #E calculated with Virus for cell
PIC$E_DS_lith <- (PIC$beta_DS_lith*ViNum) #E calculated with Virus for lith
ggplotly(ggplot(data=PIC, aes(x=PICpercellpg, y=log10(E_DS))) +geom_point(size=5, aes(shape=group2, color=Strain)) +
    theme_Publication() + geom_smooth())
`geom_smooth()` using method = 'loess' and formula 'y ~ x'
plotly.js does not (yet) support horizontal legend items 
You can track progress here: 
https://github.com/plotly/plotly.js/issues/53 

#remove strains 621, 623, 625
PIC <- PIC %>% filter (! Strain %in% c("621", "623", "655"))
ggplot(data=PIC, aes(x=PICpercellpg, y=E_DS, color=Strain,  shape=group2)) + geom_point(size=5)+theme_Publication()+
  scale_y_log10(
        breaks = scales::trans_breaks("log10", function(x) 10^x, n=2),
        labels = scales::trans_format("log10", scales::math_format(10^.x))) + annotation_logticks(sides="l") +
      theme(legend.direction = "horizontal", legend.box = "vertical", legend.title = element_blank()) +
  labs(y = expression("viral encounters " ~ day^-1~cell^-1), x = expression("PIC pg"~cell^-1))

ggplot(data=PIC %>% filter (group =="calcified"), aes(x=perlithpg, y=E_DS_lith, color=Strain,  shape=group2)) + geom_point(size=5)+theme_Publication()+
  scale_y_log10(
        breaks = scales::trans_breaks("log10", function(x) 10^x, n=2),
        labels = scales::trans_format("log10", scales::math_format(10^.x))) + annotation_logticks(sides="l") +
      theme(legend.direction = "horizontal", legend.box = "vertical", legend.title = element_blank()) +
  labs(y = expression("viral encounters " ~ day^-1~cell^-1), x = expression("PIC pg"~lith^-1))

#7. summaries
library(plyr)
summary_DS <- ddply(PIC, .(Strain), summarize,  PICpercellpg=mean(PICpercellpg), perlithpg = mean(perlithpg), 
                    Den_celltotal = mean (Den_celltotal),SinkVel=mean(SinkVel),beta_DS=mean(beta_DS), E_DS= mean(E_DS),
                    Denlith = mean (Denlith), SinkVel_lith=mean (SinkVel_lith), 
                    beta_DS_lith=mean (beta_DS_lith), E_DS_lith=mean (E_DS_lith))
summary_DS_bygroup2 <- ddply(PIC, .(group2), summarize,  PICpercellpg=mean(PICpercellpg), perlithpg = mean(perlithpg), 
                    Den_celltotal = mean (Den_celltotal), SinkVel=mean(SinkVel),beta_DS=mean(beta_DS), E_DS= mean(E_DS),
                    Denlith = mean (Denlith), SinkVel_lith=mean (SinkVel_lith), 
                    beta_DS_lith=mean (beta_DS_lith), E_DS_lith=mean (E_DS_lith))
summary_DS_bygroup <- ddply(PIC %>% filter (! group2 %in% c("naked/calcified uncertain")) , .(group), 
                            summarize,  PICpercellpg=mean(PICpercellpg), perlithpg = mean(perlithpg), 
                    Den_celltotal = mean (Den_celltotal), SinkVel=mean(SinkVel),beta_DS=mean(beta_DS), E_DS= mean(E_DS),
                    Denlith = mean (Denlith), SinkVel_lith=mean (SinkVel_lith), 
                    beta_DS_lith=mean (beta_DS_lith), E_DS_lith=mean (E_DS_lith))
summary_DS
summary_DS_bygroup2
summary_DS_bygroup
setwd("D:/R program")
The working directory was changed to D:/R program inside a notebook chunk. The working directory will be reset when the chunk is finished running. Use the knitr root.dir option in the setup chunk to change the working directory for notebook chunks.
require(openxlsx)
write.xlsx(summary_DS, file = "Postdoc-R/Exported Tables/summary_DS_master3.xlsx")
write.xlsx(summary_DS_bygroup, file = "Postdoc-R/Exported Tables/summary_DS_bygroup_master3.xlsx")
write.xlsx(summary_DS_bygroup2, file = "Postdoc-R/Exported Tables/summary_DS_bygroup2_master3.xlsx")
#8. regressions
#8a. PIC and beta_DS of cells 
PIC_beta_reg <- lm (beta_DS ~ PICpercellpg, data=PIC)
summary(PIC_beta_reg)

Call:
lm(formula = beta_DS ~ PICpercellpg, data = PIC)

Residuals:
       Min         1Q     Median         3Q        Max 
-2.465e-07 -6.697e-08 -3.387e-09  7.849e-08  1.981e-07 

Coefficients:
              Estimate Std. Error t value Pr(>|t|)    
(Intercept)  1.074e-07  2.634e-08   4.076  0.00025 ***
PICpercellpg 3.305e-07  3.096e-09 106.755  < 2e-16 ***
---
Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1

Residual standard error: 1.196e-07 on 35 degrees of freedom
Multiple R-squared:  0.9969,    Adjusted R-squared:  0.9969 
F-statistic: 1.14e+04 on 1 and 35 DF,  p-value: < 2.2e-16
plot(residuals.lm(PIC_beta_reg))

coef(PIC_beta_reg)
 (Intercept) PICpercellpg 
1.073674e-07 3.305428e-07 
cor(PIC$PICpercellpg, PIC$beta_DS)
[1] 0.998468
#8d other regressions, change this
PIC_Den_celltotal_reg <- lm(Den_celltotal ~ PICpercellpg, data=PIC)
PIC_SinkVel_reg <- lm (SinkVel ~ PICpercellpg, data=PIC)
plot(residuals.lm(PIC_Den_celltotal_reg))

plot(residuals.lm(PIC_SinkVel_reg))

#9. make a prediction based on PIC values
#9a. for cells
require(truncnorm)
require(Rmisc)
summary(PIC$PICpercellpg)
   Min. 1st Qu.  Median    Mean 3rd Qu.    Max. 
-0.4144  1.0497  2.9736  5.6575  7.0660 20.1442 
summarySE(data=PIC, measurevar="PICpercellpg")
#make new dataframe
PIC_newdata <- as.data.frame(rtruncnorm(n=10000, a=-0.4, b=20.2, mean=5.7, sd=6.4))
#rename column. rename function in plyr 
library(plyr)
PIC_newdata <- plyr::rename (PIC_newdata, c ("rtruncnorm(n = 10000, a = -0.4, b = 20.2, mean = 5.7, sd = 6.4)" = "PICpercellpg"))
PIC_newdata <- mutate(PIC_newdata, group = ifelse(PICpercellpg < 4 , "naked", "calcified"))
ggplotly(ggplot(data=PIC_newdata, aes(x=group, y=PICpercellpg)) + geom_boxplot()+geom_point(size=2) +
           theme_Publication())

#5. calculate betas for DS
PIC_newdata$beta_DS <-(pi*(((PIC_newdata$rad+Rehv)*100)^2)*(abs((PIC_newdata$SinkVel-Ehv_SinkVel)/864)))*86400 #in encounters cm3/day
PIC_newdata$beta_DS_lith <- (pi*(((Reh_lith+Rehv)*100)^2)*(abs((PIC_newdata$SinkVel_lith-Ehv_SinkVel)/864)))*86400 #in encounters cm3/day
ggplot(data=PIC_newdata %>% filter (!(group2 %in% c("naked/calcified uncertain"))), aes(x=PICpercellpg , y=beta_DS, color=group2,  shape=group2)) + geom_point(size=5)+theme_Publication()+
  labs(y = expression(beta~("Encounters"~cm^3~day^-1)), x = expression("PIC pg"~cell^-1))  +
scale_y_log10(
        breaks = scales::trans_breaks("log10", function(x) 10^x, n=2),
        labels = scales::trans_format("log10", scales::math_format(10^.x))) + annotation_logticks(sides="l")+
      theme(legend.direction = "horizontal", legend.box = "vertical", legend.title = element_blank()) 

ggplot(data=PIC_newdata %>% filter (group=="calcified"), aes(x=perlithpg, y=beta_DS_lith, color=group2, shape=group2)) + geom_point(size=5)+theme_Publication()+
  labs(y = expression(beta~("Encounters"~cm^3~day^-1)), x = expression("PIC pg"~lith^-1))  +
scale_y_log10(
        breaks = scales::trans_breaks("log10", function(x) 10^x, n=2),
        labels = scales::trans_format("log10", scales::math_format(10^.x))) + annotation_logticks(sides="l")+
      theme(legend.direction = "horizontal", legend.box = "vertical", legend.title = element_blank()) 

      
#6. calculate encounters
PIC_newdata$E_DS <- (PIC_newdata$beta_DS*ViNum) #E calculated with Virus for cell
PIC_newdata$E_DS_lith <- (PIC_newdata$beta_DS_lith*ViNum) #E calculated with Virus for lith
ggplotly(ggplot(data=PIC_newdata, aes(x=PICpercellpg, y=log10(E_DS))) +geom_point(size=5, aes(shape=group2, color=group2)) +
    theme_Publication() + geom_smooth())
`geom_smooth()` using method = 'gam' and formula 'y ~ s(x, bs = "cs")'
plotly.js does not (yet) support horizontal legend items 
You can track progress here: 
https://github.com/plotly/plotly.js/issues/53 

#remove strains 621, 623, 625
ggplot(data=PIC_newdata %>% filter (!(group2 %in% c("naked/calcified uncertain"))) , aes(x=PICpercellpg, y=E_DS, color=group2,  shape=group2)) + geom_point(size=5)+theme_Publication()+
  scale_y_log10(
        breaks = scales::trans_breaks("log10", function(x) 10^x, n=2),
        labels = scales::trans_format("log10", scales::math_format(10^.x))) + annotation_logticks(sides="l") +
      theme(legend.direction = "horizontal", legend.box = "vertical", legend.title = element_blank()) +
  labs(y = expression("viral encounters " ~ day^-1~cell^-1), x = expression("PIC pg"~cell^-1))

ggplot(data=PIC_newdata %>% filter (group =="calcified"), aes(x=perlithpg, y=E_DS_lith, color=group2,  shape=group2)) + geom_point(size=5)+theme_Publication()+
  scale_y_log10(
        breaks = scales::trans_breaks("log10", function(x) 10^x, n=2),
        labels = scales::trans_format("log10", scales::math_format(10^.x))) + annotation_logticks(sides="l") +
      theme(legend.direction = "horizontal", legend.box = "vertical", legend.title = element_blank()) +
  labs(y = expression("viral encounters " ~ day^-1~cell^-1), x = expression("PIC pg"~lith^-1))

Turbulence

#Turbulence
#1. make new dataframe
#disrate is cm2/s3
#make data frame
disrate <- rep_len (c (1 %o% 10^(seq(-8,-2, 0.5))), length.out=39)
calc <- rep_len(c("Cc"), length.out=13)
naked <- rep_len(c("Nc"), length.out=13)
lith <- rep_len(c("Li"), length.out=13)
group <- c(naked, calc, lith)
turb <- as.data.frame(cbind(disrate, group))
turb$rad <- case_when(
    turb$group =="Nc" ~ 1.8E-6,
    turb$group =="Cc" ~ 2.3E-6,
    turb$group =="Li" ~ 1.3E-6,
    TRUE ~ as.numeric(turb$group)
)
turb$disrate <- as.numeric(as.character(turb$disrate))
#2. calculate beta and encounters
turb$beta_turb <- (4.2*pi*((turb$disrate/(v*100^2))^0.5)*(((turb$rad+Rehv)*100)^3))*86400 
turb$E_turb <- (turb$beta_turb*ViNum) #E calculated with virus only
turb$group <- factor (turb$group,levels= c("Nc", "Cc", "Li"), labels = c("Nc", "Cc", "Li"))
ggplot(data = turb, aes(x = disrate, y = beta_turb, color=group)) + geom_point(size =5) +
  scale_y_log10(
        breaks = scales::trans_breaks("log10", function(x) 10^x, n=4),
        labels = scales::trans_format("log10", scales::math_format(10^.x))) +
  scale_x_log10(
        breaks = scales::trans_breaks("log10", function(x) 10^x, n=4),
        labels = scales::trans_format("log10", scales::math_format(10^.x))) +
  annotation_logticks() +
  theme_Publication() +
  labs(y = expression(beta~("predicted encounters " ~cm^3~day^-1)), 
       x = expression("dissipation rate "~(m^2~s^-3))) +
   theme(legend.title = element_blank())

ggplot(data = turb, aes(x = disrate, y = E_turb, color=group)) + geom_point(size =5) +
   scale_y_log10(
        breaks = scales::trans_breaks("log10", function(x) 10^x, n=4),
        labels = scales::trans_format("log10", scales::math_format(10^.x))) +
  scale_x_log10(
        breaks = scales::trans_breaks("log10", function(x) 10^x, n=7),
        labels = scales::trans_format("log10", scales::math_format(10^.x))) +
  annotation_logticks()+
  theme_Publication()+
  labs(y = expression("viral encounters " ~ cm^-3~day^-1),x = expression("dissipation rate "~(m^2~s^-3))) +
  theme(legend.title = element_blank())

melt all data and make a table with all

all <- Reduce(function(x,y) merge(x,y,by="group",all=TRUE) ,
              list(BM %>% select (group, beta_BM), DS_pred %>% select (group, beta_DS), 
                   turb %>% select (group, disrate, beta_turb)))
all$beta_all <- all$beta_BM + all$beta_DS + all$beta_turb
all$E_all_low <- all$beta_all*(10^4)
all$E_all_high <- all$beta_all*(10^6)
all$group <- factor (all$group,levels= c("Nc", "Cc", "Li"), labels = c("Nc", "Cc", "Li"))
#plotting
ggplot(data=all, aes(x=disrate,y = E_all_low, color=group)) + 
  geom_line(size=1, position=position_jitter(w=0.02, h=0), aes(linetype="10^3"))+
  geom_line(data = all, aes(y= E_all_high, color=group, linetype="10^5")) +
   scale_y_log10(
        breaks = scales::trans_breaks("log10", function(x) 10^x, n=2),
        labels = scales::trans_format("log10", scales::math_format(10^.x))) +
  scale_x_log10(
        breaks = scales::trans_breaks("log10", function(x) 10^x, n=7),
        labels = scales::trans_format("log10", scales::math_format(10^.x))) +
  annotation_logticks()+
  theme_Publication() +
  theme(legend.title = element_blank(), legend.key.width=unit(1,"cm"))+
  labs(y = expression("viral encounters " ~day^-1~cell^-1), x = expression("dissipation rate "~(m^2~s^-3))) +
  theme(legend.title = element_blank())

LS0tDQp0aXRsZTogImJldGEga2VybmVsIGZvciBwYXBlciINCm91dHB1dDogaHRtbF9ub3RlYm9vaw0KLS0tDQoNClRoaXMgaXMgYW4gW1IgTWFya2Rvd25dKGh0dHA6Ly9ybWFya2Rvd24ucnN0dWRpby5jb20pIE5vdGVib29rLiBXaGVuIHlvdSBleGVjdXRlIGNvZGUgd2l0aGluIHRoZSBub3RlYm9vaywgdGhlIHJlc3VsdHMgYXBwZWFyIGJlbmVhdGggdGhlIGNvZGUuIA0KDQpUaGlzIHZlcnNpb24gb2YgYmV0YSBjYWxjdWxhdGlvbiBpcyB1c2VkIGZvciB0aGUgdGhlb3JldGljYWwgbWV0aG9kL3Jlc3VsdHMgb2YgdGhlIHBhcGVyLiBGb3IgcmVmZXJlbmNlOiB0aGUgbGFzdCB1cGRhdGUgd2FzIERlYyAyMDE4IGZvciBhbiBSIG5vdGVib29rLiBUaGlzIFIgbm90ZWJvb2sgaXMgYW4gdXBkYXRlZCBhbmQgbW9yZSBzb3BoaXN0aWNhdGVkIHZlcnNpb24uIA0KDQpDb25zdGFudHMgdXNlZCBhcmUgbGlzdGVkIGF0IHRoZSBzdGFydCBvZiB0aGlzIHNjcmlwdC4NCg0KYGBge3J9DQpzZXR3ZCgiRDovUiBwcm9ncmFtIikNCnNvdXJjZSgiaW5zcGFjay5SIikNCiN2YWx1ZXMgbmVlZGVkIA0KDQpLPSAxLjM4MDY0ODUyKigxMCleLTIzICNtMiBrZy8gczIgSyBib2x0em1hbm4gY29uc3RhbnQNCm11PSAxLjEyNiooMTApXi0zICNrZy9tIHMgZHluYW1pYyB2aXNjb3NpdHkgaW4gMThDDQp2PSAxLjA5OSooMTApXi02ICNtMi9zIGtpbmVtYXRpYyB2aXNjb3NpdHkgaW4gMThDDQpSZWhfY2FsYz0gMi4zRS02ICNpbiBtIHJhZGl1cyBFaHV4DQpSZWhfbmFrZWQ9IDEuOEUtNiAjaW4gbSByYWRpdXMgRWh1eA0KUmVoX2xpdGggPSAxLjNFLTYgI2luIG0gcmFkaXVzDQpSZWh2PSA5MCooMTApXi05ICNpbiBtIHJhZGl1cyB2aXJ1cw0KVGVtcCA9IDE4KzI3My4xNSAjdGVtcCBpbiBrZWx2aW4sIGhlcmUgYXNzdW1pbmcgMThDDQpEZW5fT2NNID0gMS4wNSAjZy9jbTMgZGVuc2l0eSBvcmdhbmljIGNlbGwgbWF0dGVyDQpEZW5fQ0gyTz0gMS4wMjUgI2cvY20zIGRlbnNpdHkgc2Vhd2F0ZXIgYXQgMThDDQpDY051bSA8LSAwLjkqKCgxMCleMykNCk5jTnVtIDwtIDAuMSooKDEwKV4zKQ0KVmlOdW0gPC0gKENjTnVtK05jTnVtKSoxMA0KTGlOdW0gPC0gQ2NOdW0qNTANCmBgYA0KDQpDYWxjdWxhdGluZyBmb3IgQnJvd25pYW4gbW90aW9uDQoNCmBgYHtyfQ0KI0Jyb3duaWFuIG1vdGlvbiAoQk0pDQojMS4gbWFrZSBhIGRhdGEgZnJhbWUNCkJNIDwtIGRhdGEuZnJhbWUgKGdyb3VwPWFzLmZhY3RvcihjKCJOYyIsICJDYyIsICJMaSIpKSwgcmFkPSBjKDEuOEUtNiwgMi4zRS02LCAxLjNFLTYpKSANCg0KIzIuIGNhbGN1bGF0ZSBiZXRhIChiZXRhKQ0KQk0kYmV0YV9CTSA8LSAoKDIqKEsqKDEwKV40KSpUZW1wKigoKEJNJHJhZCtSZWh2KSoxMDApXjIpKS8oKDMqbXUqMTApKihCTSRyYWQqUmVodioxZTQpKSkqODY0MDAgI2NtMy9kDQoNCiMgZ28gYmFjayB0byB0aGlzIGxhdGVyDQojMy4gY2FsY3VsYXRlIGVuY291bnRlcnMgKEUpDQpCTSRFX0JNIDwtIEJNJGJldGFfQk0qVmlOdW0NCg0KQk0NCmBgYA0KDQpEaWZmZXJlbnRpYWwgc2V0dGxpbmcNCmBgYHtyfQ0KI0RpZmZlcmVudGlhbCBzZXR0bGluZyAoRFMpDQojMS4gcmVhZCBpbiBQSUMgZGF0YQ0KbGlicmFyeShyZWFkcikgI2Fsd2F5cyB1c2UgcmVhZHIgbm90IGJhc2VSDQoNCnNldHdkKCJEOi9SIHByb2dyYW0iKQ0KUElDIDwtIHJlYWRfY3N2KCJQb3N0ZG9jLVIvQ1NWIEZpbGVzL1BJQy5jc3YiKQ0KDQpQSUMkU3RyYWluIDwtIGFzLmZhY3RvcihQSUMkU3RyYWluKQ0KUElDJFJlcGxpY2F0ZSA8LSBhcy5mYWN0b3IoUElDJFJlcGxpY2F0ZSkNCg0KIzIuIGNhbGN1bGF0ZSBQSUMgZm9yIGNlbGwNClBJQyRQSUMgPC0gUElDJFRDLVBJQyRBQw0KUElDJFBJQ3BlcmNlbGwgPC0gKFBJQyRQSUMvUElDJENlbGxjb3VudCkqKDEwKV4tMyNpbiBnDQpQSUMkUElDcGVyY2VsbHBnIDwtIFBJQyRQSUNwZXJjZWxsKjFlMTINCg0KZ2dwbG90bHkoZ2dwbG90KGRhdGE9UElDLCBhZXMoeD1TdHJhaW4sIHk9UElDcGVyY2VsbHBnKSkgKyBnZW9tX2JveHBsb3QoKStnZW9tX3BvaW50KHNpemU9MikgK3RoZW1lX1B1YmxpY2F0aW9uKCkpDQoNCiMzYS4gY2FsY3VsYXRlIGRlbnNpdHkgb2YgY2VsbHMgKGRlbl9jZWxsKQ0KUElDIDwtIG11dGF0ZShQSUMsIGdyb3VwID0gaWZlbHNlKFBJQ3BlcmNlbGxwZyA8IDQgLCAibmFrZWQiLCAiY2FsY2lmaWVkIikpDQoNCmdncGxvdGx5KGdncGxvdChkYXRhPVBJQywgYWVzKHg9Z3JvdXAsIHk9UElDcGVyY2VsbHBnKSkgKyBnZW9tX2JveHBsb3QoKStnZW9tX3BvaW50KHNpemU9MiwgYWVzKGNvbG9yPVN0cmFpbikpKyB0aGVtZV9QdWJsaWNhdGlvbigpKQ0KDQpQSUMgPC0gbXV0YXRlKFBJQywgcmFkID0gaWZlbHNlKGdyb3VwID09ICJuYWtlZCIgLCAxLjhFLTYsICAyLjNFLTYpKSAjaW4gbQ0KDQpQSUMkdm9sdW1lIDwtICg0LzMpKnBpKihQSUMkcmFkKjEwMCleMyAjaW4gY20zDQpQSUMkRGVuX2NlbGwgPC0gUElDJFBJQ3BlcmNlbGwvUElDJHZvbHVtZSAjZy9jbTMNClBJQyREZW5fY2VsbHRvdGFsIDwtIFBJQyREZW5fY2VsbCtEZW5fT2NNDQoNCmdncGxvdGx5KGdncGxvdChkYXRhPVBJQywgYWVzKHg9U3RyYWluLCB5PURlbl9jZWxsdG90YWwsIGNvbG9yPWdyb3VwKSkgKyBnZW9tX2JveHBsb3QoKStnZW9tX3BvaW50KHNpemU9MikgDQogICAgICAgICArdGhlbWVfUHVibGljYXRpb24oKSkNCg0KDQojc29tZSBzdHJhaW5zIHRoYXQgYXJlICJuYWtlZCIgaGF2ZSBQSUM8Mi4gSSBjaG9zZSB0byBpZ25vcmUgdGhpcyBzaW5jZSBpbiB0aGUgbG0gbW9kZWwgSSBkbyBub3QgdXNlDQojc3RyYWluIGFzIGEgZmFjdG9yLCByYXRoZXIgZGF0YSBpcyB0cmVhdGVkIGFzIGEgd2hvbGUgKGUuZy4sIG5vIGdyb3VwaW5nKQ0KDQoNCmBgYA0KYGBge3J9DQojYXNzdW1lIGdyb3VwaW5nDQpQSUMkZ3JvdXAyIDwtIGNhc2Vfd2hlbigNCiAgUElDJFBJQ3BlcmNlbGxwZyA8MiAgfiAibmFrZWQiLA0KICBQSUMkUElDcGVyY2VsbHBnID4yICYgUElDJFBJQ3BlcmNlbGxwZyA8IDQgfiAibmFrZWQvY2FsY2lmaWVkIHVuY2VydGFpbiIsDQogIFBJQyRQSUNwZXJjZWxscGcgPjQgJiBQSUMkUElDcGVyY2VsbHBnIDwgMTAgfiAibW9kZXJhdGVseSBjYWxjaWZpZWQiLA0KICBQSUMkUElDcGVyY2VsbHBnID4xMCB+ICJoZWF2aWx5IGNhbGNpZmllZCIsIA0KICBUUlVFIH4gYXMuY2hhcmFjdGVyKFBJQyRQSUNwZXJjZWxscGcpDQopDQoNClBJQyRncm91cDIgPC0gZmFjdG9yIChQSUMkZ3JvdXAyLGxldmVscz0gYygibmFrZWQiLCAibmFrZWQvY2FsY2lmaWVkIHVuY2VydGFpbiIsDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIm1vZGVyYXRlbHkgY2FsY2lmaWVkIiwgImhlYXZpbHkgY2FsY2lmaWVkIiksDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbGFiZWxzID0gYygibmFrZWQiLCAibmFrZWQvY2FsY2lmaWVkIHVuY2VydGFpbiIsDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAibW9kZXJhdGVseSBjYWxjaWZpZWQiLCAiaGVhdmlseSBjYWxjaWZpZWQiKSkNCg0KIzNiLiBjYWxjdWxhdGUgUElDIGFuZCBkZW5zaXR5IGZvciBsaXRoDQpQSUMkcGVybGl0aCA8LSBQSUMkUElDcGVyY2VsbC8xNCAjaW4gZywgYXNzdW1pbmcgMjAgbGl0aHMgYXR0YWNoZWQNClBJQyRwZXJsaXRocGcgPC0gUElDJHBlcmxpdGgqMWUxMiAjaW4gcGcNClBJQyREZW5saXRoIDwtIGNhc2Vfd2hlbigNCiAgUElDJGdyb3VwMiA9PSAibmFrZWQiICB+IDEuMDI1LCANCiAgUElDJGdyb3VwMiA9PSAibmFrZWQvY2FsY2lmaWVkIHVuY2VydGFpbiIgfiAxLjAyNSwNCiAgUElDJGdyb3VwMiA9PSAibW9kZXJhdGVseSBjYWxjaWZpZWQiIH4gMiwNCiAgUElDJGdyb3VwMiA9PSAiaGVhdmlseSBjYWxjaWZpZWQiIH4gMi42KQ0KDQpnZ3Bsb3RseShnZ3Bsb3QoZGF0YT1QSUMsIGFlcyh4PWdyb3VwLCB5PURlbmxpdGgsIGNvbG9yPWdyb3VwKSkgKyBnZW9tX2JveHBsb3QoKStnZW9tX3BvaW50KHNpemU9MikgDQogICAgICAgICArdGhlbWVfUHVibGljYXRpb24oKSkNCg0KYGBgDQoNCmBgYHtyfQ0KIzQuIGNhbGN1bGF0ZSBzaW5raW5nIHZlbG9jaXR5IG9mIGNlbGxzLGxpdGhzLCBhbmQgdmlydXNlcw0KUElDJFNpbmtWZWwgPC0gKCgyKigoUElDJHJhZCoxMDApXjIpKig5ODEpKihQSUMkRGVuX2NlbGx0b3RhbC1EZW5fQ0gyTykpLyg5KihtdSoxMCkpKSo4NjQgI21ldGVyIHBlciBkYXkNClBJQyRTaW5rVmVsX2xpdGggPC0gKCgyKigoUmVoX2xpdGgqMTAwKV4yKSooOTgxKSooUElDJERlbmxpdGgtRGVuX0NIMk8pKS8oOSoobXUqMTApKSkqODY0ICNtZXRlciBwZXIgZGF5DQpFaHZfU2lua1ZlbCA8LSAoKDIqKChSZWh2KjEwMCleMikqKDk4MSkqKERlbl9DSDJPLURlbl9DSDJPKSkvKDkqKG11KjEwKSkpKjg2NCAgI2VxdWFscyB0byAwDQojZyBpcyBjb252ZXJ0ZWQgdG8gcGVyIGRheSwgODY0IGlzIHRoZSBvbmUgdGhhdCBjb252ZXJ0cyBjbS9zIHRvIG0vZGF5DQojcGxvdCBzaW5raW5nIHZlbG9jaXR5IHZzIGNhbGNpZmljYXRpb24NCg0KDQpnZ3Bsb3QoZGF0YT1QSUMsIGFlcyh4PVBJQ3BlcmNlbGxwZywgeT1TaW5rVmVsLCBjb2xvcj1TdHJhaW4sIHNoYXBlPWdyb3VwMikpICsgZ2VvbV9wb2ludChzaXplPTUpK3RoZW1lX1B1YmxpY2F0aW9uKCkrDQogICAgbGFicyh5ID0gZXhwcmVzc2lvbigiU2lua2luZyB2ZWxvY2l0eSJ+KCJtIn5kYXleLTEpKSwgeCA9IGV4cHJlc3Npb24oIlBJQyBwZyJ+Y2VsbF4tMSkpICsNCiAgICB0aGVtZShsZWdlbmQuZGlyZWN0aW9uID0gImhvcml6b250YWwiLCBsZWdlbmQuYm94ID0gInZlcnRpY2FsIiwgbGVnZW5kLnRpdGxlID0gZWxlbWVudF9ibGFuaygpKSANCg0KZ2dwbG90KGRhdGE9UElDICU+JSBmaWx0ZXIgKGdyb3VwPT0iY2FsY2lmaWVkIiksIGFlcyh4PXBlcmxpdGhwZywgeT1TaW5rVmVsX2xpdGgsIGNvbG9yPWdyb3VwMiwgc2hhcGU9Z3JvdXAyKSkgKyANCiAgZ2VvbV9wb2ludChzaXplPTUpK3RoZW1lX1B1YmxpY2F0aW9uKCkrDQogIGxhYnMoeSA9IGV4cHJlc3Npb24oIlNpbmtpbmcgdmVsb2NpdHkifigibSJ+ZGF5Xi0xKSksIHggPSBleHByZXNzaW9uKCJQSUMgcGcifmxpdGheLTEpKSArDQogICAgdGhlbWUobGVnZW5kLmRpcmVjdGlvbiA9ICJob3Jpem9udGFsIiwgbGVnZW5kLmJveCA9ICJ2ZXJ0aWNhbCIsIGxlZ2VuZC50aXRsZSA9IGVsZW1lbnRfYmxhbmsoKSkgDQoNCg0KYGBgDQpgYGB7cn0NCiM1LiBjYWxjdWxhdGUgYmV0YXMgZm9yIERTDQpQSUMkYmV0YV9EUyA8LShwaSooKChQSUMkcmFkK1JlaHYpKjEwMCleMikqKGFicygoUElDJFNpbmtWZWwtRWh2X1NpbmtWZWwpLzg2NCkpKSo4NjQwMCAjaW4gZW5jb3VudGVycyBjbTMvZGF5DQpQSUMkYmV0YV9EU19saXRoIDwtIChwaSooKChSZWhfbGl0aCtSZWh2KSoxMDApXjIpKihhYnMoKFBJQyRTaW5rVmVsX2xpdGgtRWh2X1NpbmtWZWwpLzg2NCkpKSo4NjQwMCAjaW4gZW5jb3VudGVycyBjbTMvZGF5DQoNCmdncGxvdChkYXRhPVBJQywgYWVzKHg9UElDcGVyY2VsbHBnLCB5PWJldGFfRFMsIGNvbG9yPVN0cmFpbiwgIHNoYXBlPWdyb3VwMikpICsgZ2VvbV9wb2ludChzaXplPTUpK3RoZW1lX1B1YmxpY2F0aW9uKCkrDQogIGxhYnMoeSA9IGV4cHJlc3Npb24oYmV0YX4oIkVuY291bnRlcnMifmNtXjN+ZGF5Xi0xKSksIHggPSBleHByZXNzaW9uKCJQSUMgcGcifmNlbGxeLTEpKSAgKw0Kc2NhbGVfeV9sb2cxMCgNCiAgICAgICAgYnJlYWtzID0gc2NhbGVzOjp0cmFuc19icmVha3MoImxvZzEwIiwgZnVuY3Rpb24oeCkgMTBeeCwgbj0yKSwNCiAgICAgICAgbGFiZWxzID0gc2NhbGVzOjp0cmFuc19mb3JtYXQoImxvZzEwIiwgc2NhbGVzOjptYXRoX2Zvcm1hdCgxMF4ueCkpKSArIGFubm90YXRpb25fbG9ndGlja3Moc2lkZXM9ImwiKSsNCiAgICAgIHRoZW1lKGxlZ2VuZC5kaXJlY3Rpb24gPSAiaG9yaXpvbnRhbCIsIGxlZ2VuZC5ib3ggPSAidmVydGljYWwiLCBsZWdlbmQudGl0bGUgPSBlbGVtZW50X2JsYW5rKCkpIA0KDQpnZ3Bsb3QoZGF0YT1QSUMgJT4lIGZpbHRlciAoZ3JvdXA9PSJjYWxjaWZpZWQiKSwgYWVzKHg9cGVybGl0aHBnLCB5PWJldGFfRFNfbGl0aCwgY29sb3I9Z3JvdXAyLCBzaGFwZT1ncm91cDIpKSArIGdlb21fcG9pbnQoc2l6ZT01KSt0aGVtZV9QdWJsaWNhdGlvbigpKw0KICBsYWJzKHkgPSBleHByZXNzaW9uKGJldGF+KCJFbmNvdW50ZXJzIn5jbV4zfmRheV4tMSkpLCB4ID0gZXhwcmVzc2lvbigiUElDIHBnIn5saXRoXi0xKSkgICsNCnNjYWxlX3lfbG9nMTAoDQogICAgICAgIGJyZWFrcyA9IHNjYWxlczo6dHJhbnNfYnJlYWtzKCJsb2cxMCIsIGZ1bmN0aW9uKHgpIDEwXngsIG49MiksDQogICAgICAgIGxhYmVscyA9IHNjYWxlczo6dHJhbnNfZm9ybWF0KCJsb2cxMCIsIHNjYWxlczo6bWF0aF9mb3JtYXQoMTBeLngpKSkgKyBhbm5vdGF0aW9uX2xvZ3RpY2tzKHNpZGVzPSJsIikrDQogICAgICB0aGVtZShsZWdlbmQuZGlyZWN0aW9uID0gImhvcml6b250YWwiLCBsZWdlbmQuYm94ID0gInZlcnRpY2FsIiwgbGVnZW5kLnRpdGxlID0gZWxlbWVudF9ibGFuaygpKSANCg0KYGBgDQoNCg0KYGBge3J9DQojNi4gY2FsY3VsYXRlIGVuY291bnRlcnMNClBJQyRFX0RTIDwtIChQSUMkYmV0YV9EUypWaU51bSkgI0UgY2FsY3VsYXRlZCB3aXRoIFZpcnVzIGZvciBjZWxsDQpQSUMkRV9EU19saXRoIDwtIChQSUMkYmV0YV9EU19saXRoKlZpTnVtKSAjRSBjYWxjdWxhdGVkIHdpdGggVmlydXMgZm9yIGxpdGgNCg0KZ2dwbG90bHkoZ2dwbG90KGRhdGE9UElDLCBhZXMoeD1QSUNwZXJjZWxscGcsIHk9bG9nMTAoRV9EUykpKSArZ2VvbV9wb2ludChzaXplPTUsIGFlcyhzaGFwZT1ncm91cDIsIGNvbG9yPVN0cmFpbikpICsNCiAgICB0aGVtZV9QdWJsaWNhdGlvbigpICsgZ2VvbV9zbW9vdGgoKSkNCiNyZW1vdmUgc3RyYWlucyA2MjEsIDYyMywgNjI1DQpQSUMgPC0gUElDICU+JSBmaWx0ZXIgKCEgU3RyYWluICVpbiUgYygiNjIxIiwgIjYyMyIsICI2NTUiKSkNCg0KZ2dwbG90KGRhdGE9UElDLCBhZXMoeD1QSUNwZXJjZWxscGcsIHk9RV9EUywgY29sb3I9U3RyYWluLCAgc2hhcGU9Z3JvdXAyKSkgKyBnZW9tX3BvaW50KHNpemU9NSkrdGhlbWVfUHVibGljYXRpb24oKSsNCiAgc2NhbGVfeV9sb2cxMCgNCiAgICAgICAgYnJlYWtzID0gc2NhbGVzOjp0cmFuc19icmVha3MoImxvZzEwIiwgZnVuY3Rpb24oeCkgMTBeeCwgbj0yKSwNCiAgICAgICAgbGFiZWxzID0gc2NhbGVzOjp0cmFuc19mb3JtYXQoImxvZzEwIiwgc2NhbGVzOjptYXRoX2Zvcm1hdCgxMF4ueCkpKSArIGFubm90YXRpb25fbG9ndGlja3Moc2lkZXM9ImwiKSArDQogICAgICB0aGVtZShsZWdlbmQuZGlyZWN0aW9uID0gImhvcml6b250YWwiLCBsZWdlbmQuYm94ID0gInZlcnRpY2FsIiwgbGVnZW5kLnRpdGxlID0gZWxlbWVudF9ibGFuaygpKSArDQogIGxhYnMoeSA9IGV4cHJlc3Npb24oInZpcmFsIGVuY291bnRlcnMgIiB+IGRheV4tMX5jZWxsXi0xKSwgeCA9IGV4cHJlc3Npb24oIlBJQyBwZyJ+Y2VsbF4tMSkpDQoNCmdncGxvdChkYXRhPVBJQyAlPiUgZmlsdGVyIChncm91cCA9PSJjYWxjaWZpZWQiKSwgYWVzKHg9cGVybGl0aHBnLCB5PUVfRFNfbGl0aCwgY29sb3I9U3RyYWluLCAgc2hhcGU9Z3JvdXAyKSkgKyBnZW9tX3BvaW50KHNpemU9NSkrdGhlbWVfUHVibGljYXRpb24oKSsNCiAgc2NhbGVfeV9sb2cxMCgNCiAgICAgICAgYnJlYWtzID0gc2NhbGVzOjp0cmFuc19icmVha3MoImxvZzEwIiwgZnVuY3Rpb24oeCkgMTBeeCwgbj0yKSwNCiAgICAgICAgbGFiZWxzID0gc2NhbGVzOjp0cmFuc19mb3JtYXQoImxvZzEwIiwgc2NhbGVzOjptYXRoX2Zvcm1hdCgxMF4ueCkpKSArIGFubm90YXRpb25fbG9ndGlja3Moc2lkZXM9ImwiKSArDQogICAgICB0aGVtZShsZWdlbmQuZGlyZWN0aW9uID0gImhvcml6b250YWwiLCBsZWdlbmQuYm94ID0gInZlcnRpY2FsIiwgbGVnZW5kLnRpdGxlID0gZWxlbWVudF9ibGFuaygpKSArDQogIGxhYnMoeSA9IGV4cHJlc3Npb24oInZpcmFsIGVuY291bnRlcnMgIiB+IGRheV4tMX5jZWxsXi0xKSwgeCA9IGV4cHJlc3Npb24oIlBJQyBwZyJ+bGl0aF4tMSkpDQpgYGANCg0KYGBge3J9DQojNy4gc3VtbWFyaWVzDQpsaWJyYXJ5KHBseXIpDQpzdW1tYXJ5X0RTIDwtIGRkcGx5KFBJQywgLihTdHJhaW4pLCBzdW1tYXJpemUsICBQSUNwZXJjZWxscGc9bWVhbihQSUNwZXJjZWxscGcpLCBwZXJsaXRocGcgPSBtZWFuKHBlcmxpdGhwZyksIA0KICAgICAgICAgICAgICAgICAgICBEZW5fY2VsbHRvdGFsID0gbWVhbiAoRGVuX2NlbGx0b3RhbCksU2lua1ZlbD1tZWFuKFNpbmtWZWwpLGJldGFfRFM9bWVhbihiZXRhX0RTKSwgRV9EUz0gbWVhbihFX0RTKSwNCiAgICAgICAgICAgICAgICAgICAgRGVubGl0aCA9IG1lYW4gKERlbmxpdGgpLCBTaW5rVmVsX2xpdGg9bWVhbiAoU2lua1ZlbF9saXRoKSwgDQogICAgICAgICAgICAgICAgICAgIGJldGFfRFNfbGl0aD1tZWFuIChiZXRhX0RTX2xpdGgpLCBFX0RTX2xpdGg9bWVhbiAoRV9EU19saXRoKSkNCnN1bW1hcnlfRFNfYnlncm91cDIgPC0gZGRwbHkoUElDLCAuKGdyb3VwMiksIHN1bW1hcml6ZSwgIFBJQ3BlcmNlbGxwZz1tZWFuKFBJQ3BlcmNlbGxwZyksIHBlcmxpdGhwZyA9IG1lYW4ocGVybGl0aHBnKSwgDQogICAgICAgICAgICAgICAgICAgIERlbl9jZWxsdG90YWwgPSBtZWFuIChEZW5fY2VsbHRvdGFsKSwgU2lua1ZlbD1tZWFuKFNpbmtWZWwpLGJldGFfRFM9bWVhbihiZXRhX0RTKSwgRV9EUz0gbWVhbihFX0RTKSwNCiAgICAgICAgICAgICAgICAgICAgRGVubGl0aCA9IG1lYW4gKERlbmxpdGgpLCBTaW5rVmVsX2xpdGg9bWVhbiAoU2lua1ZlbF9saXRoKSwgDQogICAgICAgICAgICAgICAgICAgIGJldGFfRFNfbGl0aD1tZWFuIChiZXRhX0RTX2xpdGgpLCBFX0RTX2xpdGg9bWVhbiAoRV9EU19saXRoKSkNCg0Kc3VtbWFyeV9EU19ieWdyb3VwIDwtIGRkcGx5KFBJQyAlPiUgZmlsdGVyICghIGdyb3VwMiAlaW4lIGMoIm5ha2VkL2NhbGNpZmllZCB1bmNlcnRhaW4iKSkgLCAuKGdyb3VwKSwgDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgc3VtbWFyaXplLCAgUElDcGVyY2VsbHBnPW1lYW4oUElDcGVyY2VsbHBnKSwgcGVybGl0aHBnID0gbWVhbihwZXJsaXRocGcpLCANCiAgICAgICAgICAgICAgICAgICAgRGVuX2NlbGx0b3RhbCA9IG1lYW4gKERlbl9jZWxsdG90YWwpLCBTaW5rVmVsPW1lYW4oU2lua1ZlbCksYmV0YV9EUz1tZWFuKGJldGFfRFMpLCBFX0RTPSBtZWFuKEVfRFMpLA0KICAgICAgICAgICAgICAgICAgICBEZW5saXRoID0gbWVhbiAoRGVubGl0aCksIFNpbmtWZWxfbGl0aD1tZWFuIChTaW5rVmVsX2xpdGgpLCANCiAgICAgICAgICAgICAgICAgICAgYmV0YV9EU19saXRoPW1lYW4gKGJldGFfRFNfbGl0aCksIEVfRFNfbGl0aD1tZWFuIChFX0RTX2xpdGgpKQ0Kc3VtbWFyeV9EUw0Kc3VtbWFyeV9EU19ieWdyb3VwMg0Kc3VtbWFyeV9EU19ieWdyb3VwDQpzZXR3ZCgiRDovUiBwcm9ncmFtIikNCnJlcXVpcmUob3Blbnhsc3gpDQp3cml0ZS54bHN4KHN1bW1hcnlfRFMsIGZpbGUgPSAiUG9zdGRvYy1SL0V4cG9ydGVkIFRhYmxlcy9zdW1tYXJ5X0RTX21hc3RlcjMueGxzeCIpDQp3cml0ZS54bHN4KHN1bW1hcnlfRFNfYnlncm91cCwgZmlsZSA9ICJQb3N0ZG9jLVIvRXhwb3J0ZWQgVGFibGVzL3N1bW1hcnlfRFNfYnlncm91cF9tYXN0ZXIzLnhsc3giKQ0Kd3JpdGUueGxzeChzdW1tYXJ5X0RTX2J5Z3JvdXAyLCBmaWxlID0gIlBvc3Rkb2MtUi9FeHBvcnRlZCBUYWJsZXMvc3VtbWFyeV9EU19ieWdyb3VwMl9tYXN0ZXIzLnhsc3giKQ0KYGBgDQoNCmBgYHtyfQ0KIzguIHJlZ3Jlc3Npb25zDQojOGEuIFBJQyBhbmQgYmV0YV9EUyBvZiBjZWxscyANClBJQ19iZXRhX3JlZyA8LSBsbSAoYmV0YV9EUyB+IFBJQ3BlcmNlbGxwZywgZGF0YT1QSUMpDQpzdW1tYXJ5KFBJQ19iZXRhX3JlZykNCnBsb3QocmVzaWR1YWxzLmxtKFBJQ19iZXRhX3JlZykpDQpjb2VmKFBJQ19iZXRhX3JlZykNCmNvcihQSUMkUElDcGVyY2VsbHBnLCBQSUMkYmV0YV9EUykNCg0KIzhkIG90aGVyIHJlZ3Jlc3Npb25zLCBjaGFuZ2UgdGhpcw0KUElDX0Rlbl9jZWxsdG90YWxfcmVnIDwtIGxtKERlbl9jZWxsdG90YWwgfiBQSUNwZXJjZWxscGcsIGRhdGE9UElDKQ0KUElDX1NpbmtWZWxfcmVnIDwtIGxtIChTaW5rVmVsIH4gUElDcGVyY2VsbHBnLCBkYXRhPVBJQykNCg0KcGxvdChyZXNpZHVhbHMubG0oUElDX0Rlbl9jZWxsdG90YWxfcmVnKSkNCnBsb3QocmVzaWR1YWxzLmxtKFBJQ19TaW5rVmVsX3JlZykpDQoNCmBgYA0KDQpgYGB7cn0NCiM5LiBtYWtlIGEgcHJlZGljdGlvbiBiYXNlZCBvbiBQSUMgdmFsdWVzDQojOWEuIGZvciBjZWxscw0KcmVxdWlyZSh0cnVuY25vcm0pDQpyZXF1aXJlKFJtaXNjKQ0Kc3VtbWFyeShQSUMkUElDcGVyY2VsbHBnKQ0Kc3VtbWFyeVNFKGRhdGE9UElDLCBtZWFzdXJldmFyPSJQSUNwZXJjZWxscGciKQ0KDQojbWFrZSBuZXcgZGF0YWZyYW1lDQpQSUNfbmV3ZGF0YSA8LSBhcy5kYXRhLmZyYW1lKHJ0cnVuY25vcm0obj0xMDAwMCwgYT0tMC40LCBiPTIwLjIsIG1lYW49NS43LCBzZD02LjQpKQ0KI3JlbmFtZSBjb2x1bW4uIHJlbmFtZSBmdW5jdGlvbiBpbiBwbHlyIA0KbGlicmFyeShwbHlyKQ0KUElDX25ld2RhdGEgPC0gcGx5cjo6cmVuYW1lIChQSUNfbmV3ZGF0YSwgYyAoInJ0cnVuY25vcm0obiA9IDEwMDAwLCBhID0gLTAuNCwgYiA9IDIwLjIsIG1lYW4gPSA1LjcsIHNkID0gNi40KSIgPSAiUElDcGVyY2VsbHBnIikpDQpQSUNfbmV3ZGF0YSA8LSBtdXRhdGUoUElDX25ld2RhdGEsIGdyb3VwID0gaWZlbHNlKFBJQ3BlcmNlbGxwZyA8IDQgLCAibmFrZWQiLCAiY2FsY2lmaWVkIikpDQpnZ3Bsb3RseShnZ3Bsb3QoZGF0YT1QSUNfbmV3ZGF0YSwgYWVzKHg9Z3JvdXAsIHk9UElDcGVyY2VsbHBnKSkgKyBnZW9tX2JveHBsb3QoKStnZW9tX3BvaW50KHNpemU9MikgKw0KICAgICAgICAgICB0aGVtZV9QdWJsaWNhdGlvbigpKQ0KDQpgYGANCmBgYHtyfQ0KUElDX25ld2RhdGEkZ3JvdXAyIDwtIGNhc2Vfd2hlbigNCiAgUElDX25ld2RhdGEkUElDcGVyY2VsbHBnIDwyICB+ICJuYWtlZCIsDQogIFBJQ19uZXdkYXRhJFBJQ3BlcmNlbGxwZyA+MiAmIFBJQ19uZXdkYXRhJFBJQ3BlcmNlbGxwZyA8IDQgfiAibmFrZWQvY2FsY2lmaWVkIHVuY2VydGFpbiIsDQogIFBJQ19uZXdkYXRhJFBJQ3BlcmNlbGxwZyA+NCAmIFBJQ19uZXdkYXRhJFBJQ3BlcmNlbGxwZyA8IDEwIH4gIm1vZGVyYXRlbHkgY2FsY2lmaWVkIiwNCiAgUElDX25ld2RhdGEkUElDcGVyY2VsbHBnID4xMCB+ICJoZWF2aWx5IGNhbGNpZmllZCIsIA0KICBUUlVFIH4gYXMuY2hhcmFjdGVyKFBJQ19uZXdkYXRhJFBJQ3BlcmNlbGxwZykNCikNCg0KUElDX25ld2RhdGEkZ3JvdXAyIDwtIGZhY3RvciAoUElDX25ld2RhdGEkZ3JvdXAyLGxldmVscz0gYygibmFrZWQiLCAibmFrZWQvY2FsY2lmaWVkIHVuY2VydGFpbiIsDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIm1vZGVyYXRlbHkgY2FsY2lmaWVkIiwgImhlYXZpbHkgY2FsY2lmaWVkIiksDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbGFiZWxzID0gYygibmFrZWQiLCAibmFrZWQvY2FsY2lmaWVkIHVuY2VydGFpbiIsDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAibW9kZXJhdGVseSBjYWxjaWZpZWQiLCAiaGVhdmlseSBjYWxjaWZpZWQiKSkNCg0KI2NhbGN1bGF0ZSBuZXcgc3R1ZmYNCg0KUElDX25ld2RhdGEgPC0gbXV0YXRlKFBJQ19uZXdkYXRhLCByYWQgPSBpZmVsc2UoZ3JvdXAgPT0gIm5ha2VkIiAsIDEuOEUtNiwgIDIuM0UtNikpICNpbiBtDQoNClBJQ19uZXdkYXRhJHZvbHVtZSA8LSAoNC8zKSpwaSooUElDX25ld2RhdGEkcmFkKjEwMCleMyAjaW4gY20zDQpQSUNfbmV3ZGF0YSREZW5fY2VsbCA8LSAoUElDX25ld2RhdGEkUElDcGVyY2VsbCoxZS0xMikvUElDX25ld2RhdGEkdm9sdW1lICNnL2NtMw0KUElDX25ld2RhdGEkRGVuX2NlbGx0b3RhbCA8LSBQSUNfbmV3ZGF0YSREZW5fY2VsbCtEZW5fT2NNDQoNCmdncGxvdGx5KGdncGxvdChkYXRhPVBJQywgYWVzKHg9U3RyYWluLCB5PURlbl9jZWxsdG90YWwsIGNvbG9yPWdyb3VwKSkgKyBnZW9tX2JveHBsb3QoKStnZW9tX3BvaW50KHNpemU9MikgDQogICAgICAgICArdGhlbWVfUHVibGljYXRpb24oKSkNCg0KDQojM2IuIGNhbGN1bGF0ZSBQSUMgYW5kIGRlbnNpdHkgZm9yIGxpdGgNClBJQ19uZXdkYXRhJHBlcmxpdGhwZyA8LSBQSUNfbmV3ZGF0YSRQSUNwZXJjZWxscGcvMTQgI2luIGcsIGFzc3VtaW5nIDIwIGxpdGhzIGF0dGFjaGVkDQpQSUNfbmV3ZGF0YSREZW5saXRoIDwtIGNhc2Vfd2hlbigNCiAgUElDX25ld2RhdGEkZ3JvdXAyID09ICJuYWtlZCIgIH4gMS4wMjUsIA0KICBQSUNfbmV3ZGF0YSRncm91cDIgPT0gIm5ha2VkL2NhbGNpZmllZCB1bmNlcnRhaW4iIH4gMS4wMjUsDQogIFBJQ19uZXdkYXRhJGdyb3VwMiA9PSAibW9kZXJhdGVseSBjYWxjaWZpZWQiIH4gMiwNCiAgUElDX25ld2RhdGEkZ3JvdXAyID09ICJoZWF2aWx5IGNhbGNpZmllZCIgfiAyLjYpDQoNCmdncGxvdGx5KGdncGxvdChkYXRhPVBJQ19uZXdkYXRhLCBhZXMoeD1ncm91cCwgeT1EZW5saXRoLCBjb2xvcj1ncm91cCkpICsgZ2VvbV9ib3hwbG90KCkrZ2VvbV9wb2ludChzaXplPTIpIA0KICAgICAgICAgK3RoZW1lX1B1YmxpY2F0aW9uKCkpDQoNCiM0LiBjYWxjdWxhdGUgc2lua2luZyB2ZWxvY2l0eSBvZiBjZWxscyxsaXRocywgYW5kIHZpcnVzZXMNClBJQ19uZXdkYXRhJFNpbmtWZWwgPC0gKCgyKigoUElDX25ld2RhdGEkcmFkKjEwMCleMikqKDk4MSkqKFBJQ19uZXdkYXRhJERlbl9jZWxsdG90YWwtRGVuX0NIMk8pKS8oOSoobXUqMTApKSkqODY0ICNtZXRlciBwZXIgZGF5DQpQSUNfbmV3ZGF0YSRTaW5rVmVsX2xpdGggPC0gKCgyKigoUmVoX2xpdGgqMTAwKV4yKSooOTgxKSooUElDX25ld2RhdGEkRGVubGl0aC1EZW5fQ0gyTykpLyg5KihtdSoxMCkpKSo4NjQgI21ldGVyIHBlciBkYXkNCkVodl9TaW5rVmVsIDwtICgoMiooKFJlaHYqMTAwKV4yKSooOTgxKSooRGVuX0NIMk8tRGVuX0NIMk8pKS8oOSoobXUqMTApKSkqODY0ICAjZXF1YWxzIHRvIDANCiNnIGlzIGNvbnZlcnRlZCB0byBwZXIgZGF5LCA4NjQgaXMgdGhlIG9uZSB0aGF0IGNvbnZlcnRzIGNtL3MgdG8gbS9kYXkNCiNwbG90IHNpbmtpbmcgdmVsb2NpdHkgdnMgY2FsY2lmaWNhdGlvbg0KDQoNCmdncGxvdChkYXRhPVBJQ19uZXdkYXRhLCBhZXMoeD1QSUNwZXJjZWxscGcsIHk9U2lua1ZlbCwgY29sb3I9Z3JvdXAyLCBzaGFwZT1ncm91cDIpKSArIGdlb21fcG9pbnQoc2l6ZT01KSt0aGVtZV9QdWJsaWNhdGlvbigpKw0KICAgIGxhYnMoeSA9IGV4cHJlc3Npb24oIlNpbmtpbmcgdmVsb2NpdHkifigibSJ+ZGF5Xi0xKSksIHggPSBleHByZXNzaW9uKCJQSUMgcGcifmNlbGxeLTEpKSArDQogICAgdGhlbWUobGVnZW5kLmRpcmVjdGlvbiA9ICJob3Jpem9udGFsIiwgbGVnZW5kLmJveCA9ICJ2ZXJ0aWNhbCIsIGxlZ2VuZC50aXRsZSA9IGVsZW1lbnRfYmxhbmsoKSkgDQoNCmdncGxvdChkYXRhPVBJQ19uZXdkYXRhICU+JSBmaWx0ZXIgKGdyb3VwPT0iY2FsY2lmaWVkIiksIGFlcyh4PXBlcmxpdGhwZywgeT1TaW5rVmVsX2xpdGgsIGNvbG9yPWdyb3VwMiwgc2hhcGU9Z3JvdXAyKSkgKyANCiAgZ2VvbV9wb2ludChzaXplPTUpK3RoZW1lX1B1YmxpY2F0aW9uKCkrDQogIGxhYnMoeSA9IGV4cHJlc3Npb24oIlNpbmtpbmcgdmVsb2NpdHkifigibSJ+ZGF5Xi0xKSksIHggPSBleHByZXNzaW9uKCJQSUMgcGcifmxpdGheLTEpKSArDQogICAgdGhlbWUobGVnZW5kLmRpcmVjdGlvbiA9ICJob3Jpem9udGFsIiwgbGVnZW5kLmJveCA9ICJ2ZXJ0aWNhbCIsIGxlZ2VuZC50aXRsZSA9IGVsZW1lbnRfYmxhbmsoKSkgDQoNCg0KDQpgYGANCmBgYHtyfQ0KDQojNS4gY2FsY3VsYXRlIGJldGFzIGZvciBEUw0KUElDX25ld2RhdGEkYmV0YV9EUyA8LShwaSooKChQSUNfbmV3ZGF0YSRyYWQrUmVodikqMTAwKV4yKSooYWJzKChQSUNfbmV3ZGF0YSRTaW5rVmVsLUVodl9TaW5rVmVsKS84NjQpKSkqODY0MDAgI2luIGVuY291bnRlcnMgY20zL2RheQ0KUElDX25ld2RhdGEkYmV0YV9EU19saXRoIDwtIChwaSooKChSZWhfbGl0aCtSZWh2KSoxMDApXjIpKihhYnMoKFBJQ19uZXdkYXRhJFNpbmtWZWxfbGl0aC1FaHZfU2lua1ZlbCkvODY0KSkpKjg2NDAwICNpbiBlbmNvdW50ZXJzIGNtMy9kYXkNCg0KZ2dwbG90KGRhdGE9UElDX25ld2RhdGEgJT4lIGZpbHRlciAoIShncm91cDIgJWluJSBjKCJuYWtlZC9jYWxjaWZpZWQgdW5jZXJ0YWluIikpKSwgYWVzKHg9UElDcGVyY2VsbHBnICwgeT1iZXRhX0RTLCBjb2xvcj1ncm91cDIsICBzaGFwZT1ncm91cDIpKSArIGdlb21fcG9pbnQoc2l6ZT01KSt0aGVtZV9QdWJsaWNhdGlvbigpKw0KICBsYWJzKHkgPSBleHByZXNzaW9uKGJldGF+KCJFbmNvdW50ZXJzIn5jbV4zfmRheV4tMSkpLCB4ID0gZXhwcmVzc2lvbigiUElDIHBnIn5jZWxsXi0xKSkgICsNCnNjYWxlX3lfbG9nMTAoDQogICAgICAgIGJyZWFrcyA9IHNjYWxlczo6dHJhbnNfYnJlYWtzKCJsb2cxMCIsIGZ1bmN0aW9uKHgpIDEwXngsIG49MiksDQogICAgICAgIGxhYmVscyA9IHNjYWxlczo6dHJhbnNfZm9ybWF0KCJsb2cxMCIsIHNjYWxlczo6bWF0aF9mb3JtYXQoMTBeLngpKSkgKyBhbm5vdGF0aW9uX2xvZ3RpY2tzKHNpZGVzPSJsIikrDQogICAgICB0aGVtZShsZWdlbmQuZGlyZWN0aW9uID0gImhvcml6b250YWwiLCBsZWdlbmQuYm94ID0gInZlcnRpY2FsIiwgbGVnZW5kLnRpdGxlID0gZWxlbWVudF9ibGFuaygpKSANCg0KZ2dwbG90KGRhdGE9UElDX25ld2RhdGEgJT4lIGZpbHRlciAoZ3JvdXA9PSJjYWxjaWZpZWQiKSwgYWVzKHg9cGVybGl0aHBnLCB5PWJldGFfRFNfbGl0aCwgY29sb3I9Z3JvdXAyLCBzaGFwZT1ncm91cDIpKSArIGdlb21fcG9pbnQoc2l6ZT01KSt0aGVtZV9QdWJsaWNhdGlvbigpKw0KICBsYWJzKHkgPSBleHByZXNzaW9uKGJldGF+KCJFbmNvdW50ZXJzIn5jbV4zfmRheV4tMSkpLCB4ID0gZXhwcmVzc2lvbigiUElDIHBnIn5saXRoXi0xKSkgICsNCnNjYWxlX3lfbG9nMTAoDQogICAgICAgIGJyZWFrcyA9IHNjYWxlczo6dHJhbnNfYnJlYWtzKCJsb2cxMCIsIGZ1bmN0aW9uKHgpIDEwXngsIG49MiksDQogICAgICAgIGxhYmVscyA9IHNjYWxlczo6dHJhbnNfZm9ybWF0KCJsb2cxMCIsIHNjYWxlczo6bWF0aF9mb3JtYXQoMTBeLngpKSkgKyBhbm5vdGF0aW9uX2xvZ3RpY2tzKHNpZGVzPSJsIikrDQogICAgICB0aGVtZShsZWdlbmQuZGlyZWN0aW9uID0gImhvcml6b250YWwiLCBsZWdlbmQuYm94ID0gInZlcnRpY2FsIiwgbGVnZW5kLnRpdGxlID0gZWxlbWVudF9ibGFuaygpKSANCgkgIA0KIzYuIGNhbGN1bGF0ZSBlbmNvdW50ZXJzDQpQSUNfbmV3ZGF0YSRFX0RTIDwtIChQSUNfbmV3ZGF0YSRiZXRhX0RTKlZpTnVtKSAjRSBjYWxjdWxhdGVkIHdpdGggVmlydXMgZm9yIGNlbGwNClBJQ19uZXdkYXRhJEVfRFNfbGl0aCA8LSAoUElDX25ld2RhdGEkYmV0YV9EU19saXRoKlZpTnVtKSAjRSBjYWxjdWxhdGVkIHdpdGggVmlydXMgZm9yIGxpdGgNCg0KZ2dwbG90bHkoZ2dwbG90KGRhdGE9UElDX25ld2RhdGEsIGFlcyh4PVBJQ3BlcmNlbGxwZywgeT1sb2cxMChFX0RTKSkpICtnZW9tX3BvaW50KHNpemU9NSwgYWVzKHNoYXBlPWdyb3VwMiwgY29sb3I9Z3JvdXAyKSkgKw0KICAgIHRoZW1lX1B1YmxpY2F0aW9uKCkgKyBnZW9tX3Ntb290aCgpKQ0KI3JlbW92ZSBzdHJhaW5zIDYyMSwgNjIzLCA2MjUNCg0KZ2dwbG90KGRhdGE9UElDX25ld2RhdGEgJT4lIGZpbHRlciAoIShncm91cDIgJWluJSBjKCJuYWtlZC9jYWxjaWZpZWQgdW5jZXJ0YWluIikpKSAsIGFlcyh4PVBJQ3BlcmNlbGxwZywgeT1FX0RTLCBjb2xvcj1ncm91cDIsICBzaGFwZT1ncm91cDIpKSArIGdlb21fcG9pbnQoc2l6ZT01KSt0aGVtZV9QdWJsaWNhdGlvbigpKw0KICBzY2FsZV95X2xvZzEwKA0KICAgICAgICBicmVha3MgPSBzY2FsZXM6OnRyYW5zX2JyZWFrcygibG9nMTAiLCBmdW5jdGlvbih4KSAxMF54LCBuPTIpLA0KICAgICAgICBsYWJlbHMgPSBzY2FsZXM6OnRyYW5zX2Zvcm1hdCgibG9nMTAiLCBzY2FsZXM6Om1hdGhfZm9ybWF0KDEwXi54KSkpICsgYW5ub3RhdGlvbl9sb2d0aWNrcyhzaWRlcz0ibCIpICsNCiAgICAgIHRoZW1lKGxlZ2VuZC5kaXJlY3Rpb24gPSAiaG9yaXpvbnRhbCIsIGxlZ2VuZC5ib3ggPSAidmVydGljYWwiLCBsZWdlbmQudGl0bGUgPSBlbGVtZW50X2JsYW5rKCkpICsNCiAgbGFicyh5ID0gZXhwcmVzc2lvbigidmlyYWwgZW5jb3VudGVycyAiIH4gZGF5Xi0xfmNlbGxeLTEpLCB4ID0gZXhwcmVzc2lvbigiUElDIHBnIn5jZWxsXi0xKSkNCg0KZ2dwbG90KGRhdGE9UElDX25ld2RhdGEgJT4lIGZpbHRlciAoZ3JvdXAgPT0iY2FsY2lmaWVkIiksIGFlcyh4PXBlcmxpdGhwZywgeT1FX0RTX2xpdGgsIGNvbG9yPWdyb3VwMiwgIHNoYXBlPWdyb3VwMikpICsgZ2VvbV9wb2ludChzaXplPTUpK3RoZW1lX1B1YmxpY2F0aW9uKCkrDQogIHNjYWxlX3lfbG9nMTAoDQogICAgICAgIGJyZWFrcyA9IHNjYWxlczo6dHJhbnNfYnJlYWtzKCJsb2cxMCIsIGZ1bmN0aW9uKHgpIDEwXngsIG49MiksDQogICAgICAgIGxhYmVscyA9IHNjYWxlczo6dHJhbnNfZm9ybWF0KCJsb2cxMCIsIHNjYWxlczo6bWF0aF9mb3JtYXQoMTBeLngpKSkgKyBhbm5vdGF0aW9uX2xvZ3RpY2tzKHNpZGVzPSJsIikgKw0KICAgICAgdGhlbWUobGVnZW5kLmRpcmVjdGlvbiA9ICJob3Jpem9udGFsIiwgbGVnZW5kLmJveCA9ICJ2ZXJ0aWNhbCIsIGxlZ2VuZC50aXRsZSA9IGVsZW1lbnRfYmxhbmsoKSkgKw0KICBsYWJzKHkgPSBleHByZXNzaW9uKCJ2aXJhbCBlbmNvdW50ZXJzICIgfiBkYXleLTF+Y2VsbF4tMSksIHggPSBleHByZXNzaW9uKCJQSUMgcGcifmxpdGheLTEpKQ0KYGBgDQoNCmBgYHtyfQ0KIzEwLiBjYWxjdWxhdGUgZW5jb3VudGVycyBiYXNlZCBvbiBuZXdkYXRhDQoNCnN1bW1hcnlfRFNfYnlncm91cDwtZGRwbHkoUElDICU+JSBmaWx0ZXIgKCEoZ3JvdXAyICVpbiUgYygibmFrZWQvY2FsY2lmaWVkIHVuY2VydGFpbiIpKSksIC4oZ3JvdXApLCBzdW1tYXJpemUsICBQSUNwZXJjZWxscGc9bWVhbihQSUNwZXJjZWxscGcpLCANCiAgICAgICAgICAgICAgICAgICAgcGVybGl0aHBnID0gbWVhbihwZXJsaXRocGcpLCBEZW5fY2VsbHRvdGFsID0gbWVhbiAoRGVuX2NlbGx0b3RhbCksDQogICAgICAgICAgICAgICAgICAgIFNpbmtWZWw9bWVhbihTaW5rVmVsKSxiZXRhX0RTPW1lYW4oYmV0YV9EUyksIEVfRFM9IG1lYW4oRV9EUyksIA0KICAgICAgICAgICAgICAgICAgICBEZW5saXRoID0gbWVhbiAoRGVubGl0aCksIFNpbmtWZWxfbGl0aD1tZWFuIChTaW5rVmVsX2xpdGgpLCANCiAgICAgICAgICAgICAgICAgICAgYmV0YV9EU19saXRoPW1lYW4gKGJldGFfRFNfbGl0aCksIEVfRFNfbGl0aD1tZWFuIChFX0RTX2xpdGgpKQ0Kc3VtbWFyeV9EU19ieWdyb3VwDQoNCiNyZW1vdmUgbmFrZWQvY2FsY2lmaWVkIHVuY2VydGFpbg0KDQpzdW1tYXJ5X0RTX2J5Z3JvdXBfcHJlZCA8LWRkcGx5KFBJQ19uZXdkYXRhICU+JSBmaWx0ZXIgKCEoZ3JvdXAyICVpbiUgYygibmFrZWQvY2FsY2lmaWVkIHVuY2VydGFpbiIpKSksIC4oZ3JvdXApLCBzdW1tYXJpemUsICBQSUNwZXJjZWxscGc9bWVhbihQSUNwZXJjZWxscGcpLCANCiAgICAgICAgICAgICAgICAgICAgcGVybGl0aHBnID0gbWVhbihwZXJsaXRocGcpLCBEZW5fY2VsbHRvdGFsID0gbWVhbiAoRGVuX2NlbGx0b3RhbCksDQogICAgICAgICAgICAgICAgICAgIFNpbmtWZWw9bWVhbihTaW5rVmVsKSxiZXRhX0RTPW1lYW4oYmV0YV9EUyksIEVfRFM9IG1lYW4oRV9EUyksIA0KICAgICAgICAgICAgICAgICAgICBEZW5saXRoID0gbWVhbiAoRGVubGl0aCksIFNpbmtWZWxfbGl0aD1tZWFuIChTaW5rVmVsX2xpdGgpLCANCiAgICAgICAgICAgICAgICAgICAgYmV0YV9EU19saXRoPW1lYW4gKGJldGFfRFNfbGl0aCksIEVfRFNfbGl0aD1tZWFuIChFX0RTX2xpdGgpKQ0Kc3VtbWFyeV9EU19ieWdyb3VwX3ByZWQNCg0Kc3VtbWFyeV9EU19ieWdyb3VwMl9wcmVkIDwtZGRwbHkoUElDX25ld2RhdGEgJT4lIGZpbHRlciAoIShncm91cDIgJWluJSBjKCJuYWtlZC9jYWxjaWZpZWQgdW5jZXJ0YWluIikpKSwgLihncm91cDIpLCBzdW1tYXJpemUsICBQSUNwZXJjZWxscGc9bWVhbihQSUNwZXJjZWxscGcpLCANCiAgICAgICAgICAgICAgICAgICAgcGVybGl0aHBnID0gbWVhbihwZXJsaXRocGcpLCBEZW5fY2VsbHRvdGFsID0gbWVhbiAoRGVuX2NlbGx0b3RhbCksDQogICAgICAgICAgICAgICAgICAgIFNpbmtWZWw9bWVhbihTaW5rVmVsKSxiZXRhX0RTPW1lYW4oYmV0YV9EUyksIEVfRFM9IG1lYW4oRV9EUyksIA0KICAgICAgICAgICAgICAgICAgICBEZW5saXRoID0gbWVhbiAoRGVubGl0aCksIFNpbmtWZWxfbGl0aD1tZWFuIChTaW5rVmVsX2xpdGgpLCANCiAgICAgICAgICAgICAgICAgICAgYmV0YV9EU19saXRoPW1lYW4gKGJldGFfRFNfbGl0aCksIEVfRFNfbGl0aD1tZWFuIChFX0RTX2xpdGgpKQ0Kc3VtbWFyeV9EU19ieWdyb3VwMl9wcmVkDQoNCnN1bW1hcnlTRSAoUElDX25ld2RhdGEgJT4lIGZpbHRlciAoIShncm91cDIgJWluJSBjKCJuYWtlZC9jYWxjaWZpZWQgdW5jZXJ0YWluIikpKSwgDQogICAgICAgICAgIG1lYXN1cmV2YXIgPSAiUElDcGVyY2VsbHBnIiwgZ3JvdXB2YXJzID0gYygiZ3JvdXAiKSkNCg0KDQpzZXR3ZCgiRDovUiBwcm9ncmFtIikNCndyaXRlLnhsc3goc3VtbWFyeV9EU19ieWdyb3VwX3ByZWQsIGZpbGUgPSAiUG9zdGRvYy1SL0V4cG9ydGVkIFRhYmxlcy9zdW1tYXJ5X0RTX2J5Z3JvdXBfcHJlZF9tYXN0ZXIzLnhsc3giKQ0KYGBgDQoNCmBgYHtyfQ0KI2FycmFuZ2UgdGhlIHN1bW1hcnkNCkRTX3ByZWQgPC0gZGF0YS5mcmFtZSAoZ3JvdXA9YXMuZmFjdG9yKGMoIk5jIiwgIkNjIiwgIkxpIikpLCByYWQ9IGMoMS44RS02LCAyLjNFLTYsIDEuM0UtNiksIA0KICAgICAgICAgICAgICAgICAgUElDPSBjKDAuODUwNDY5NSwgOS41ODYwNDIyLCAwLjY4NDcxNzMwKSwgRGVuPSBjKDEuMDg0ODE0LCAxLjIzODA5MSwyLjI0ODgyNyksDQogICAgICAgICAgICAgICAgICBTaW5rVmVsID0gYygwLjAzMjQxNzQ2LCAwLjE4ODU2MTAyLCAwLjM0NTk3KSwgDQogICAgICAgICAgICAgICAgICBiZXRhX0RTID0gYygzLjYzNzkxNGUtMDcJLCAzLjM4Mzc0NWUtMDYsIDIuMDk5OTkzZS0wNikpDQoNCkRTIDwtIGRhdGEuZnJhbWUgKGdyb3VwPWFzLmZhY3RvcihjKCJOYyIsICJDYyIsICJMaSIpKSwgcmFkPSBjKDEuOEUtNiwgMi4zRS02LCAxLjNFLTYpLA0KICAgICAgICAgICAgICAgICAgUElDID0gYygwLjY5NzkyMjIsIDExLjQ4NDAxMTksIDAuODIwMjg2NTYpLCBEZW4gPSBjKDEuMDc4NTY5LCAxLjI3NTMzMSwgMi4zMDApLA0KICAgICAgICAgICAgICAgICAgU2lua1ZlbCA9IGMgKDAuMDI5MDMzMTEsIDAuMjIxNTE0NywgMC4zNjA0MzY1KSwgDQogICAgICAgICAgICAgICAgICBiZXRhX0RTID0gYygzLjI1ODExOWUtMDcsIDMuOTc1MTAzZS0wNiwgMi4xODc4MDNlLTA2CSkpDQoNCkRTDQpEU19wcmVkDQpgYGANCg0KVHVyYnVsZW5jZQ0KYGBge3J9DQojVHVyYnVsZW5jZQ0KIzEuIG1ha2UgbmV3IGRhdGFmcmFtZQ0KI2Rpc3JhdGUgaXMgY20yL3MzDQojbWFrZSBkYXRhIGZyYW1lDQpkaXNyYXRlIDwtIHJlcF9sZW4gKGMgKDEgJW8lIDEwXihzZXEoLTgsLTIsIDAuNSkpKSwgbGVuZ3RoLm91dD0zOSkNCmNhbGMgPC0gcmVwX2xlbihjKCJDYyIpLCBsZW5ndGgub3V0PTEzKQ0KbmFrZWQgPC0gcmVwX2xlbihjKCJOYyIpLCBsZW5ndGgub3V0PTEzKQ0KbGl0aCA8LSByZXBfbGVuKGMoIkxpIiksIGxlbmd0aC5vdXQ9MTMpDQpncm91cCA8LSBjKG5ha2VkLCBjYWxjLCBsaXRoKQ0KdHVyYiA8LSBhcy5kYXRhLmZyYW1lKGNiaW5kKGRpc3JhdGUsIGdyb3VwKSkNCg0KdHVyYiRyYWQgPC0gY2FzZV93aGVuKA0KICAgIHR1cmIkZ3JvdXAgPT0iTmMiIH4gMS44RS02LA0KICAgIHR1cmIkZ3JvdXAgPT0iQ2MiIH4gMi4zRS02LA0KICAgIHR1cmIkZ3JvdXAgPT0iTGkiIH4gMS4zRS02LA0KICAgIFRSVUUgfiBhcy5udW1lcmljKHR1cmIkZ3JvdXApDQopDQp0dXJiJGRpc3JhdGUgPC0gYXMubnVtZXJpYyhhcy5jaGFyYWN0ZXIodHVyYiRkaXNyYXRlKSkNCg0KIzIuIGNhbGN1bGF0ZSBiZXRhIGFuZCBlbmNvdW50ZXJzDQp0dXJiJGJldGFfdHVyYiA8LSAoNC4yKnBpKigodHVyYiRkaXNyYXRlLyh2KjEwMF4yKSleMC41KSooKCh0dXJiJHJhZCtSZWh2KSoxMDApXjMpKSo4NjQwMCANCnR1cmIkRV90dXJiIDwtICh0dXJiJGJldGFfdHVyYipWaU51bSkgI0UgY2FsY3VsYXRlZCB3aXRoIHZpcnVzIG9ubHkNCg0KdHVyYiRncm91cCA8LSBmYWN0b3IgKHR1cmIkZ3JvdXAsbGV2ZWxzPSBjKCJOYyIsICJDYyIsICJMaSIpLCBsYWJlbHMgPSBjKCJOYyIsICJDYyIsICJMaSIpKQ0KDQpnZ3Bsb3QoZGF0YSA9IHR1cmIsIGFlcyh4ID0gZGlzcmF0ZSwgeSA9IGJldGFfdHVyYiwgY29sb3I9Z3JvdXApKSArIGdlb21fcG9pbnQoc2l6ZSA9NSkgKw0KICBzY2FsZV95X2xvZzEwKA0KICAgICAgICBicmVha3MgPSBzY2FsZXM6OnRyYW5zX2JyZWFrcygibG9nMTAiLCBmdW5jdGlvbih4KSAxMF54LCBuPTQpLA0KICAgICAgICBsYWJlbHMgPSBzY2FsZXM6OnRyYW5zX2Zvcm1hdCgibG9nMTAiLCBzY2FsZXM6Om1hdGhfZm9ybWF0KDEwXi54KSkpICsNCiAgc2NhbGVfeF9sb2cxMCgNCiAgICAgICAgYnJlYWtzID0gc2NhbGVzOjp0cmFuc19icmVha3MoImxvZzEwIiwgZnVuY3Rpb24oeCkgMTBeeCwgbj00KSwNCiAgICAgICAgbGFiZWxzID0gc2NhbGVzOjp0cmFuc19mb3JtYXQoImxvZzEwIiwgc2NhbGVzOjptYXRoX2Zvcm1hdCgxMF4ueCkpKSArDQogIGFubm90YXRpb25fbG9ndGlja3MoKSArDQogIHRoZW1lX1B1YmxpY2F0aW9uKCkgKw0KICBsYWJzKHkgPSBleHByZXNzaW9uKGJldGF+KCJwcmVkaWN0ZWQgZW5jb3VudGVycyAiIH5jbV4zfmRheV4tMSkpLCANCiAgICAgICB4ID0gZXhwcmVzc2lvbigiZGlzc2lwYXRpb24gcmF0ZSAifihtXjJ+c14tMykpKSArDQogICB0aGVtZShsZWdlbmQudGl0bGUgPSBlbGVtZW50X2JsYW5rKCkpDQoNCmdncGxvdChkYXRhID0gdHVyYiwgYWVzKHggPSBkaXNyYXRlLCB5ID0gRV90dXJiLCBjb2xvcj1ncm91cCkpICsgZ2VvbV9wb2ludChzaXplID01KSArDQogICBzY2FsZV95X2xvZzEwKA0KICAgICAgICBicmVha3MgPSBzY2FsZXM6OnRyYW5zX2JyZWFrcygibG9nMTAiLCBmdW5jdGlvbih4KSAxMF54LCBuPTQpLA0KICAgICAgICBsYWJlbHMgPSBzY2FsZXM6OnRyYW5zX2Zvcm1hdCgibG9nMTAiLCBzY2FsZXM6Om1hdGhfZm9ybWF0KDEwXi54KSkpICsNCiAgc2NhbGVfeF9sb2cxMCgNCiAgICAgICAgYnJlYWtzID0gc2NhbGVzOjp0cmFuc19icmVha3MoImxvZzEwIiwgZnVuY3Rpb24oeCkgMTBeeCwgbj03KSwNCiAgICAgICAgbGFiZWxzID0gc2NhbGVzOjp0cmFuc19mb3JtYXQoImxvZzEwIiwgc2NhbGVzOjptYXRoX2Zvcm1hdCgxMF4ueCkpKSArDQogIGFubm90YXRpb25fbG9ndGlja3MoKSsNCiAgdGhlbWVfUHVibGljYXRpb24oKSsNCiAgbGFicyh5ID0gZXhwcmVzc2lvbigidmlyYWwgZW5jb3VudGVycyAiIH4gY21eLTN+ZGF5Xi0xKSx4ID0gZXhwcmVzc2lvbigiZGlzc2lwYXRpb24gcmF0ZSAifihtXjJ+c14tMykpKSArDQogIHRoZW1lKGxlZ2VuZC50aXRsZSA9IGVsZW1lbnRfYmxhbmsoKSkNCmBgYA0KDQptZWx0IGFsbCBkYXRhIGFuZCBtYWtlIGEgdGFibGUgd2l0aCBhbGwNCmBgYHtyfQ0KYWxsIDwtIFJlZHVjZShmdW5jdGlvbih4LHkpIG1lcmdlKHgseSxieT0iZ3JvdXAiLGFsbD1UUlVFKSAsDQogICAgICAgICAgICAgIGxpc3QoQk0gJT4lIHNlbGVjdCAoZ3JvdXAsIGJldGFfQk0pLCBEU19wcmVkICU+JSBzZWxlY3QgKGdyb3VwLCBiZXRhX0RTKSwgDQogICAgICAgICAgICAgICAgICAgdHVyYiAlPiUgc2VsZWN0IChncm91cCwgZGlzcmF0ZSwgYmV0YV90dXJiKSkpDQphbGwkYmV0YV9hbGwgPC0gYWxsJGJldGFfQk0gKyBhbGwkYmV0YV9EUyArIGFsbCRiZXRhX3R1cmINCmFsbCRFX2FsbF9sb3cgPC0gYWxsJGJldGFfYWxsKigxMF40KQ0KYWxsJEVfYWxsX2hpZ2ggPC0gYWxsJGJldGFfYWxsKigxMF42KQ0KYWxsJGdyb3VwIDwtIGZhY3RvciAoYWxsJGdyb3VwLGxldmVscz0gYygiTmMiLCAiQ2MiLCAiTGkiKSwgbGFiZWxzID0gYygiTmMiLCAiQ2MiLCAiTGkiKSkNCg0KDQojcGxvdHRpbmcNCmdncGxvdChkYXRhPWFsbCwgYWVzKHg9ZGlzcmF0ZSx5ID0gRV9hbGxfbG93LCBjb2xvcj1ncm91cCkpICsgDQogIGdlb21fbGluZShzaXplPTEsIHBvc2l0aW9uPXBvc2l0aW9uX2ppdHRlcih3PTAuMDIsIGg9MCksIGFlcyhsaW5ldHlwZT0iMTBeMyIpKSsNCiAgZ2VvbV9saW5lKGRhdGEgPSBhbGwsIGFlcyh5PSBFX2FsbF9oaWdoLCBjb2xvcj1ncm91cCwgbGluZXR5cGU9IjEwXjUiKSkgKw0KICAgc2NhbGVfeV9sb2cxMCgNCiAgICAgICAgYnJlYWtzID0gc2NhbGVzOjp0cmFuc19icmVha3MoImxvZzEwIiwgZnVuY3Rpb24oeCkgMTBeeCwgbj0yKSwNCiAgICAgICAgbGFiZWxzID0gc2NhbGVzOjp0cmFuc19mb3JtYXQoImxvZzEwIiwgc2NhbGVzOjptYXRoX2Zvcm1hdCgxMF4ueCkpKSArDQogIHNjYWxlX3hfbG9nMTAoDQogICAgICAgIGJyZWFrcyA9IHNjYWxlczo6dHJhbnNfYnJlYWtzKCJsb2cxMCIsIGZ1bmN0aW9uKHgpIDEwXngsIG49NyksDQogICAgICAgIGxhYmVscyA9IHNjYWxlczo6dHJhbnNfZm9ybWF0KCJsb2cxMCIsIHNjYWxlczo6bWF0aF9mb3JtYXQoMTBeLngpKSkgKw0KICBhbm5vdGF0aW9uX2xvZ3RpY2tzKCkrDQogIHRoZW1lX1B1YmxpY2F0aW9uKCkgKw0KICB0aGVtZShsZWdlbmQudGl0bGUgPSBlbGVtZW50X2JsYW5rKCksIGxlZ2VuZC5rZXkud2lkdGg9dW5pdCgxLCJjbSIpKSsNCiAgbGFicyh5ID0gZXhwcmVzc2lvbigidmlyYWwgZW5jb3VudGVycyAiIH5kYXleLTF+Y2VsbF4tMSksIHggPSBleHByZXNzaW9uKCJkaXNzaXBhdGlvbiByYXRlICJ+KG1eMn5zXi0zKSkpICsNCiAgdGhlbWUobGVnZW5kLnRpdGxlID0gZWxlbWVudF9ibGFuaygpKQ0KYGBgDQoNCg==